package org.xtense.rcp.editors;

import java.util.List;

import org.dom4j.Node;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ViewForm;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IWorkbenchPartConstants;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.part.EditorPart;
import org.xtense.rcp.editors.action.AttributePopupActionGroup;
import org.xtense.rcp.editors.action.ElementPopupActionGroup;
import org.xtense.rcp.editors.action.RootPopupActionGroup;
import org.xtense.rcp.editors.action.XmlCellModifier;
import org.xtense.rcp.editors.action.XmlEditorActionGroup;
import org.xtense.rcp.editors.util.XmlEntry;
import org.xtense.rcp.editors.util.XmlTreeProvider;
import org.xtense.rcp.util.XmlTreeUtil;

public class XmlEditor extends EditorPart {
	public final static String Col_Name = "name";
	public final static String Col_Value = "value";
	private TreeViewer treeViewer;
	private Tree tree;
	private XmlEditorActionGroup actionGroup;
	private ToolBarManager manager;
	private RootPopupActionGroup rootActionGroup;
	private ElementPopupActionGroup elementActionGroup;
	private AttributePopupActionGroup attributeActionGroup;
	private boolean dirty = false;

	public void setDirty(boolean value) {
		dirty = value;
		firePropertyChange(IWorkbenchPartConstants.PROP_DIRTY);
	}

	@Override
	public void doSave(IProgressMonitor monitor) {
		doSaveAs();
	}

	@Override
	public void doSaveAs() {
		FileDialog fileDialog = new FileDialog(getEditorSite().getShell(),
				SWT.SAVE);
		fileDialog.setFilterExtensions(new String[] { "*.xml" });
		String path = fileDialog.open();
		XmlTreeUtil.saveXMLTree(treeViewer, path);
		setDirty(false);

	}

	@Override
	public void init(IEditorSite site, IEditorInput input)
			throws PartInitException {
		this.setSite(site);
		this.setInput(input);
	}

	@Override
	public boolean isDirty() {
		return dirty;
	}

	@Override
	public boolean isSaveAsAllowed() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public void createPartControl(Composite parent) {
		setDirty(false);
		ViewForm top = new ViewForm(parent, SWT.NONE);
		top.setLayout(new FillLayout());
		treeViewer = new TreeViewer(top, SWT.NONE);
		treeViewer.setColumnProperties((new String[] { Col_Name, Col_Value }));
		CellEditor[] editors = new CellEditor[2];
		editors[0] = new TextCellEditor(treeViewer.getTree());
		editors[1] = new TextCellEditor(treeViewer.getTree());
		treeViewer.setCellEditors(editors);
		treeViewer.setCellModifier(new XmlCellModifier(treeViewer, this));

		tree = treeViewer.getTree();
		TreeColumn tag = new TreeColumn(tree, SWT.LEAD);
		tag.setText(Col_Name);
		tag.setWidth(250);
		TreeColumn value = new TreeColumn(tree, SWT.LEAD);
		value.setText(Col_Value);
		value.setWidth(250);
		tree.setHeaderVisible(true);
		tree.setLinesVisible(true);
		treeViewer.setContentProvider(new XmlTreeProvider());
		treeViewer.setLabelProvider(new XmlTreeProvider());

		rootActionGroup = new RootPopupActionGroup(this, treeViewer);
		elementActionGroup = new ElementPopupActionGroup(this, treeViewer);
		attributeActionGroup = new AttributePopupActionGroup(this, treeViewer);
		tree.addMouseListener(new MouseAdapter() {
			public void mouseDown(MouseEvent e) {
				if (e.button == 3) {
					TreeItem treeItem = tree.getItem(new Point(e.x, e.y));

					if (treeItem != null) {
						IStructuredSelection selection = (IStructuredSelection) treeViewer
								.getSelection();
						XmlEntry entry = (XmlEntry) selection
								.getFirstElement();

						if (entry.getType() == XmlEntry.Element) {
							if (entry.getParentEntry() == null) {
								rootActionGroup.fillContextMenu();
							} else {
								elementActionGroup.fillContextMenu();
							}
						} else if (entry.getType() == XmlEntry.Attribute) {
							attributeActionGroup.fillContextMenu();
						}
					} else {
						rootActionGroup.dispose();
						elementActionGroup.dispose();
						attributeActionGroup.dispose();
					}
				} 
			}
		});

		actionGroup = new XmlEditorActionGroup(parent
				.getShell(), treeViewer, this);
		ToolBar bar = new ToolBar(top, SWT.FLAT);
		manager = new ToolBarManager(bar);
		actionGroup.fillActionToolBars(manager, true);

		top.setContent(treeViewer.getControl());
		top.setTopLeft(bar);
	}

	public void setPartName(String name) {
		super.setPartName(name);
	}

	@SuppressWarnings("unchecked")
	public void showResult(Object list) {
		if (list instanceof List)
			XmlTreeUtil.createXmlTree(treeViewer, (List<Node>) list);
	}
	
	public void updateToolBar(boolean isFromFile, int documentId) {
		actionGroup.fillActionToolBars(manager, isFromFile);
		actionGroup.setDocID(documentId);
	}

	@Override
	public void setFocus() {
		// TODO Auto-generated method stub

	}

}
